home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume14 / mush6.0 / part05 < prev    next >
Encoding:
Internet Message Format  |  1988-04-12  |  50.8 KB

  1. Subject:  v14i037:  Mail User's Shell, version 6.0, Part05/14
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: island!argv@sun.com (Dan Heller)
  7. Posting-number: Volume 14, Issue 37
  8. Archive-name: mush6.0/part05
  9.  
  10.  
  11.  
  12. #! /bin/sh
  13. # This is a shell archive.  Remove anything before this line, then unpack
  14. # it by saving it into a file and typing "sh file".  To overwrite existing
  15. # files, type "sh file -c".  You can also feed this as standard input via
  16. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  17. # will see the following message at the end:
  18. #        "End of archive 5 (of 14)."
  19. # Contents:  bind.c doproc.c main.c viewopts.c
  20. # Wrapped by rsalz@fig.bbn.com on Wed Apr 13 20:04:46 1988
  21. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  22. if test -f 'bind.c' -a "${1}" != "-c" ; then 
  23.   echo shar: Will not clobber existing file \"'bind.c'\"
  24. else
  25. echo shar: Extracting \"'bind.c'\" \(12063 characters\)
  26. sed "s/^X//" >'bind.c' <<'END_OF_FILE'
  27. X/* bind.c */
  28. X
  29. X#ifdef CURSES
  30. X
  31. X#include "bindings.h"
  32. X#include "mush.h"
  33. X
  34. X#define MAX_BIND_LEN 20   /* max length a string can be to bind to a command */
  35. X
  36. struct cmd_map {
  37. X    int m_cmd;  /* the command this is mapped to  */
  38. X    char *m_str;  /* the string user types (cbreak) */
  39. X    struct cmd_map *m_next;
  40. X} *cmd_map;
  41. X
  42. init_bindings()
  43. X{
  44. X    add_bind("g", 1);
  45. X    add_bind("w", 2);
  46. X    add_bind("W", 3);
  47. X    add_bind("s", 4);
  48. X    add_bind("S", 5);
  49. X    add_bind("c", 6);
  50. X    add_bind("C", 7);
  51. X    add_bind("d", 8);
  52. X    add_bind("D", 9);
  53. X    add_bind("u", 10);
  54. X    add_bind("U", 11);
  55. X    add_bind("\\CR", 12);
  56. X    add_bind("\\CL", 13);
  57. X    add_bind("j", 14), add_bind("J", 14), add_bind("\\n", 14), add_bind("+",14);
  58. X    add_bind("k", 15), add_bind("K", 15), add_bind("-",15), add_bind("\\CK",15);
  59. X    add_bind("^", 16);
  60. X    add_bind("$", 17);
  61. X    add_bind("{", 18);
  62. X    add_bind("}", 19);
  63. X    add_bind("z", 20);
  64. X    add_bind("Z", 21);
  65. X    add_bind("H", 22);
  66. X    add_bind("(", 23);
  67. X    add_bind(")", 24);
  68. X    add_bind("/", 25);
  69. X    add_bind("\\C_", 26);  /* this is really ^/ */
  70. X    add_bind("\\CN", 27);
  71. X    add_bind("\\CP", 28);
  72. X    add_bind("o" ,29);
  73. X    add_bind("O", 30);
  74. X    add_bind("Q", 31);
  75. X    add_bind("q", 32);
  76. X    add_bind("X", 33);
  77. X    add_bind("x", 34);
  78. X    add_bind("\\CU", 35);
  79. X    add_bind("f", 36);
  80. X    add_bind("!", 37);
  81. X    add_bind(":", 38);
  82. X    add_bind("|", 39);
  83. X    add_bind("%", 40);
  84. X    add_bind("v", 41);
  85. X    add_bind("i", 42);
  86. X    add_bind("a", 43);
  87. X    add_bind("h", 44);
  88. X    add_bind("V", 45);
  89. X    add_bind("M", 46);
  90. X    add_bind("m", 47);
  91. X    add_bind("r", 48);
  92. X    add_bind("R", 49);
  93. X    add_bind("t", 50), add_bind(".", 50), add_bind("p", 50);
  94. X    add_bind("T", 51);
  95. X    add_bind("n", 52);
  96. X    add_bind("b", 53);
  97. X    add_bind("B", 54);
  98. X    add_bind("?", 55); /* C_HELP Must be the last one! */
  99. X}
  100. X
  101. struct cmd_map map_func_names[] = {
  102. X    { C_NULL,        NULL,            NULL_MAP },
  103. X    { C_GOTO_MSG,    "goto msg",        NULL_MAP },
  104. X    { C_WRITE_MSG,    "write",        NULL_MAP },
  105. X    { C_WRITE_LIST,    "write list",        NULL_MAP },
  106. X    { C_SAVE_MSG,    "save",            NULL_MAP },
  107. X    { C_SAVE_LIST,    "save list",        NULL_MAP },
  108. X    { C_COPY_MSG,    "copy",            NULL_MAP },
  109. X    { C_COPY_LIST,    "copy list",        NULL_MAP },
  110. X    { C_DELETE_MSG,    "delete",        NULL_MAP },
  111. X    { C_DELETE_LIST,    "delete list",        NULL_MAP },
  112. X    { C_UNDEL_MSG,    "undelete",        NULL_MAP },
  113. X    { C_UNDEL_LIST,    "undelete list",    NULL_MAP },
  114. X    { C_REVERSE,    "reverse video",    NULL_MAP },
  115. X    { C_REDRAW,        "redraw",        NULL_MAP },
  116. X    { C_NEXT_MSG,    "next msg",        NULL_MAP },
  117. X    { C_PREV_MSG,    "back msg",        NULL_MAP },
  118. X    { C_FIRST_MSG,    "first msg",        NULL_MAP },
  119. X    { C_LAST_MSG,    "last msg",        NULL_MAP },
  120. X    { C_TOP_PAGE,    "top page",        NULL_MAP },
  121. X    { C_BOTTOM_PAGE,    "bottom page",        NULL_MAP },
  122. X    { C_NEXT_SCREEN,    "screen next",        NULL_MAP },
  123. X    { C_PREV_SCREEN,    "screen back",        NULL_MAP },
  124. X    { C_SHOW_HDR,    "show hdr",        NULL_MAP },
  125. X    { C_SOURCE,        "source",        NULL_MAP },
  126. X    { C_SAVEOPTS,    "saveopts",        NULL_MAP },
  127. X    { C_NEXT_SEARCH,    "search up",        NULL_MAP },
  128. X    { C_PREV_SEARCH,    "search down",        NULL_MAP },
  129. X    { C_CONT_SEARCH,    "search cont",        NULL_MAP },
  130. X    { C_PRESERVE,    "preserve",        NULL_MAP },
  131. X    { C_SORT,        "sort",            NULL_MAP },
  132. X    { C_REV_SORT,    "sort reverse",        NULL_MAP },
  133. X    { C_QUIT_HARD,    "quit!",        NULL_MAP },
  134. X    { C_QUIT,        "quit",            NULL_MAP },
  135. X    { C_EXIT_HARD,    "exit!",        NULL_MAP },
  136. X    { C_EXIT,        "exit",            NULL_MAP },
  137. X    { C_UPDATE,        "update",        NULL_MAP },
  138. X    { C_FOLDER,        "folder",        NULL_MAP },
  139. X    { C_SHELL_ESC,    "shell escape",        NULL_MAP },
  140. X    { C_CURSES_ESC,    "line mode",        NULL_MAP },
  141. X    { C_PRINT_MSG,    "lpr",            NULL_MAP },
  142. X    { C_CHDIR,        "chdir",        NULL_MAP },
  143. X    { C_VAR_SET,    "variable",        NULL_MAP },
  144. X    { C_IGNORE,        "ignore",        NULL_MAP },
  145. X    { C_ALIAS,        "alias",        NULL_MAP },
  146. X    { C_OWN_HDR,    "my hdrs",        NULL_MAP },
  147. X    { C_VERSION,    "version",        NULL_MAP },
  148. X    { C_MAIL_FLAGS,    "mail flags",        NULL_MAP },
  149. X    { C_MAIL,        "mail",            NULL_MAP },
  150. X    { C_REPLY_SENDER,    "reply",        NULL_MAP },
  151. X    { C_REPLY_ALL,    "reply all",        NULL_MAP },
  152. X    { C_DISPLAY_MSG,    "display",        NULL_MAP },
  153. X    { C_TOP_MSG,    "top",            NULL_MAP },
  154. X    { C_DISPLAY_NEXT,    "display next",        NULL_MAP },
  155. X    { C_BIND,        "bind",            NULL_MAP },
  156. X    { C_UNBIND,        "unbind",        NULL_MAP },
  157. X    { C_HELP,        "help",            NULL_MAP }
  158. X};
  159. X
  160. getcmd()
  161. X{
  162. X    char         buf[MAX_BIND_LEN];
  163. X    register int     c, m, match;
  164. X    register char    *p = buf;
  165. X    register struct cmd_map *list;
  166. X
  167. X    bzero(buf, MAX_BIND_LEN);
  168. X    c = getchar();
  169. X    /* If user did job control (^Z), then the interrupt flag will be
  170. X     * set.  Be sure it's unset before continuing.
  171. X     */
  172. X    turnoff(glob_flags, WAS_INTR);
  173. X    if (isdigit(c)) {
  174. X    (void) ungetc(c, stdin);
  175. X    return C_GOTO_MSG;
  176. X    }
  177. X    for (;; p += strlen(p), c = getchar()) {
  178. X    if (c == ESC)
  179. X        (void) strcpy(buf, "\\E");
  180. X    else if (c == '\n' || c == '\r')
  181. X        (void) strcpy(p, "\\n");
  182. X    else if (c == '\t')
  183. X        (void) strcpy(p, "\\t");
  184. X    else if (iscntrl(c))
  185. X        (void) sprintf(p, "\\C%c", upper(unctrl(c)[1]));
  186. X    else
  187. X        *p = c;
  188. X    m = 0;
  189. X    for (list = cmd_map; list; list = list->m_next)
  190. X        if ((match = prefix(buf, list->m_str)) == MATCH) {
  191. X        if (debug)
  192. X            print("\"%s\" ", map_func_names[list->m_cmd].m_str);
  193. X        return list->m_cmd;
  194. X        } else if (match != NO_MATCH)
  195. X        m++;
  196. X    if (m == 0) {
  197. X        if (debug)
  198. X        print("No binding for \"%s\" found.", buf);
  199. X        return C_NULL;
  200. X    }
  201. X    }
  202. X}
  203. X
  204. X/*
  205. X * bind chars or strings to commands -- doesn't touch messages; return -1
  206. X * for curses mode, return -2 to have curses command set CNTD_CMD to
  207. X * prevent screen refresh to allow user to read output in case of multilines.
  208. X */
  209. bind_it(len, argv)
  210. char **argv;
  211. X{
  212. X    char buf[MAX_BIND_LEN], buf2[256];
  213. X    register int x;
  214. X    int (*oldint)(), (*oldquit)();
  215. X    int unbind = (argv && **argv == 'u');
  216. X    int ret = -1; /* return value */
  217. X
  218. X    if (argv && *++argv && !strcmp(*argv, "-?"))
  219. X    return help(0, "bind", cmd_help) - 1;
  220. X
  221. X    if (iscurses)
  222. X    on_intr();
  223. X
  224. X    if (unbind) {
  225. X    if (!*argv) {
  226. X        print("Unbind what? ");
  227. X        if (Getstr(buf, MAX_BIND_LEN-1, 0) <= 0) {
  228. X        if (iscurses)
  229. X            off_intr();
  230. X        return -1;
  231. X        }
  232. X    } else
  233. X        (void) strcpy(buf, *argv);
  234. X    if (!un_bind(buf))
  235. X        print("\"%s\" isn't bound to a command.\n", buf);
  236. X    if (iscurses)
  237. X        off_intr();
  238. X    return -1;
  239. X    }
  240. X    if (argv && *argv) {
  241. X    (void) strncpy(buf, *argv, MAX_BIND_LEN-1);
  242. X    if (!argv[1]) {
  243. X        int binding = c_bind(*argv);
  244. X        if (binding)
  245. X        print("\"%s\" is bound to \"%s\".\n",
  246. X            *argv, map_func_names[binding].m_str);
  247. X        else
  248. X        print("\"%s\" isn't bound to a command.\n", *argv);
  249. X        if (iscurses)
  250. X        off_intr();
  251. X        return -1;
  252. X    } else
  253. X        argv++;
  254. X    } else {
  255. X    extern char *_unctrl[];
  256. X    register char *p, *p2 = buf2;
  257. X
  258. X    print("bind [<CR>=all, -?=help]: ");
  259. X    if ((len = Getstr(buf, MAX_BIND_LEN-1, 0)) == 0) {
  260. X        if (iscurses)
  261. X        putchar('\n');
  262. X        (void) c_bind(NULL);
  263. X        if (iscurses)
  264. X        off_intr();
  265. X        return -2;
  266. X    }
  267. X    if (len < 0) {
  268. X        if (iscurses)
  269. X        off_intr();
  270. X        return -1;
  271. X    }
  272. X    /* If user typed control chars, convert them to the \Cx format. */
  273. X    for (p = buf; *p; p++)
  274. X        if (*p == '\n' || *p == '\r')
  275. X        *p2++ = '\\', *p2++ = 'n';
  276. X        else if (*p == '\t')
  277. X        *p2++ = '\\', *p2++ = 't';
  278. X        else if (*p == ESC)
  279. X        *p2++ = '\\', *p2++ = 'E';
  280. X        else if (iscntrl(*p))
  281. X        *p2++ = '\\', *p2++ = 'C', *p2++ = _unctrl[*p][1];
  282. X        else
  283. X        *p2++ = *p;
  284. X    *p2 = 0;
  285. X    (void) strcpy(buf, buf2);
  286. X    }
  287. X    /* if a binding was given on the command line */
  288. X    if (argv && *argv)
  289. X    (void) argv_to_string(buf2, argv);
  290. X    else {
  291. X    int binding;
  292. X    
  293. X    if (!strcmp(buf, "-?")) {
  294. X        if (iscurses)
  295. X        clr_bot_line();
  296. X        (void) help(0, "bind", cmd_help);
  297. X        if (iscurses)
  298. X        off_intr();
  299. X        return -2;
  300. X    }
  301. X
  302. X    binding = c_bind(buf);
  303. X
  304. X    for (len = 0; len == 0; ) {
  305. X        print("\"%s\" = <%s>: New function [<CR> for list]: ",
  306. X        buf, (binding? map_func_names[binding].m_str : "unset"));
  307. X        len = Getstr(buf2, 29, 0);
  308. X        if (iscurses)
  309. X        clr_bot_line();
  310. X        if (len == 0) {
  311. X        char *maps[C_HELP+1], *p, *malloc();
  312. X        int n = 0;
  313. X
  314. X        if (iscurses)
  315. X            putchar('\n');
  316. X        for (x = 0; x < C_HELP; x++) {
  317. X            if (!(x % 4))
  318. X            if (!(p = maps[n++] = malloc(81))) {
  319. X                error("malloc in bind()");
  320. X                free_vec(maps);
  321. X                if (iscurses)
  322. X                off_intr();
  323. X                return -1;
  324. X            }
  325. X            p += strlen(sprintf(p, "%-18.18s  ",
  326. X                    map_func_names[x+1].m_str));
  327. X        }
  328. X        maps[n] = NULL;
  329. X        (void) help(0, maps, NULL);
  330. X        free_vec(maps);
  331. X        ret--;
  332. X        }
  333. X    }
  334. X    /* if list was printed, ret < -1 -- tells CNTD_CMD to be set and
  335. X     * prevents screen from being refreshed (lets user read output
  336. X     */
  337. X    if (len == -1) {
  338. X        if (iscurses)
  339. X        off_intr();
  340. X        return ret;
  341. X    }
  342. X    }
  343. X    for (x = 1; x <= C_HELP; x++)
  344. X    if (!strcmp(buf2, map_func_names[x].m_str)) {
  345. X        int add_to_ret;
  346. X        if (debug)
  347. X        print("\"%s\" will execute \"%s\".\n", buf, buf2);
  348. X        add_to_ret = do_bind(buf, map_func_names[x].m_cmd);
  349. X        /* if do_bind hda no errors, it returned -1.  If we already
  350. X         * messed up the screen, then ret is less than -1.  return the
  351. X         * lesser of the two to make sure that CNTD_CMD gets set right
  352. X         */
  353. X        if (iscurses)
  354. X        off_intr();
  355. X        return min(add_to_ret, ret);
  356. X    }
  357. X    print("\"%s\": Unknown function.\n", buf2);
  358. X    if (iscurses)
  359. X    off_intr();
  360. X    return ret;
  361. X}
  362. X
  363. X/*
  364. X * print current key to command bindings if "str" is NULL.
  365. X * else return the integer "m_cmd" which the str is bound to.
  366. X */
  367. c_bind(str)
  368. register char *str;
  369. X{
  370. X    register struct cmd_map *opts;
  371. X    register int    incurses = iscurses;
  372. X    char buf[128]; /* these lines can't get very long */
  373. X
  374. X    if (!str) {
  375. X    if (incurses)
  376. X        clr_bot_line(), iscurses = FALSE;
  377. X    (void) do_pager(NULL, TRUE);
  378. X    (void) do_pager("Current key to command bindings:\n\n", FALSE);
  379. X    }
  380. X
  381. X    for (opts = cmd_map; opts; opts = opts->m_next)
  382. X    if (!str) {
  383. X        if (do_pager(sprintf(buf, "%-20.20s %s\n",
  384. X             opts->m_str, map_func_names[opts->m_cmd].m_str),
  385. X             FALSE) == EOF)
  386. X        break;
  387. X    } else
  388. X        if (strcmp(str, opts->m_str))
  389. X        continue;
  390. X        else if (opts->m_cmd)
  391. X        return opts->m_cmd;
  392. X        else
  393. X        return 0;
  394. X    iscurses = incurses;
  395. X    if (str)
  396. X    (void) do_pager(NULL, FALSE);
  397. X    return 0;
  398. X}
  399. X
  400. X/*
  401. X * doesn't touch messages: return -1.  Error output causes return < -1.
  402. X */
  403. do_bind(str, func)
  404. register char *str;
  405. X{
  406. X    register struct cmd_map *list;
  407. X    register int match, ret = -1;
  408. X
  409. X    (void) un_bind(str);
  410. X    for (list = cmd_map; list; list = list->m_next)
  411. X    if ((match = prefix(str, list->m_str)) == MATCH)
  412. X        puts("Something impossible just happened."), ret--;
  413. X    else if (match == A_PREFIX_B)
  414. X        printf("Warning: \"%s\" prefixes \"%s\" (%s)\n",
  415. X        str, list->m_str, map_func_names[list->m_cmd].m_str), ret--;
  416. X    else if (match == B_PREFIX_A)
  417. X        printf("Warning: \"%s\" (%s) prefixes: \"%s\"\n",
  418. X        list->m_str, map_func_names[list->m_cmd].m_str, str), ret--;
  419. X    add_bind(str, func);
  420. X    /* errors decrement ret.  If ret returns less than -1, CNTD_CMD is set
  421. X     * and no redrawing is done so user can see the warning signs
  422. X     */
  423. X    return ret;
  424. X}
  425. X
  426. add_bind(str, func)
  427. register char *str;
  428. X{
  429. X    register struct cmd_map *tmp;
  430. X    struct cmd_map *calloc();
  431. X
  432. X    /* now make a new option struct and set fields */
  433. X    if (!(tmp = calloc((unsigned)1, sizeof(struct cmd_map)))) {
  434. X    error("calloc");
  435. X    return;
  436. X    }
  437. X    tmp->m_next = cmd_map;
  438. X    cmd_map = tmp;
  439. X
  440. X    tmp->m_str = savestr(str);
  441. X    tmp->m_cmd = func; /* strdup handles the NULL case */
  442. X}
  443. X
  444. un_bind(p)
  445. register char *p;
  446. X{
  447. X    register struct cmd_map *list = cmd_map, *tmp;
  448. X
  449. X    if (!list || !*list->m_str || !p || !*p)
  450. X    return 0;
  451. X
  452. X    if (!strcmp(p, cmd_map->m_str)) {
  453. X    cmd_map = cmd_map->m_next;
  454. X    xfree (list->m_str);
  455. X    xfree((char *)list);
  456. X    return 1;
  457. X    }
  458. X    for ( ; list->m_next; list = list->m_next)
  459. X    if (!strcmp(p, list->m_next->m_str)) {
  460. X        tmp = list->m_next;
  461. X        list->m_next = list->m_next->m_next;
  462. X        xfree (tmp->m_str);
  463. X        xfree ((char *)tmp);
  464. X        return 1;
  465. X    }
  466. X    return 0;
  467. X}
  468. X
  469. prefix(a, b)
  470. register char *a, *b;
  471. X{
  472. X    while (*a && *b && *a == *b)
  473. X    a++, b++;
  474. X    if (!*a && !*b)
  475. X    return MATCH;
  476. X    if (!*a && *b)
  477. X    return A_PREFIX_B;
  478. X    if (*a && !*b)
  479. X    return B_PREFIX_A;
  480. X    return NO_MATCH;
  481. X}
  482. X#endif /* CURSES */
  483. END_OF_FILE
  484. if test 12063 -ne `wc -c <'bind.c'`; then
  485.     echo shar: \"'bind.c'\" unpacked with wrong size!
  486. fi
  487. # end of 'bind.c'
  488. fi
  489. if test -f 'doproc.c' -a "${1}" != "-c" ; then 
  490.   echo shar: Will not clobber existing file \"'doproc.c'\"
  491. else
  492. echo shar: Extracting \"'doproc.c'\" \(12080 characters\)
  493. sed "s/^X//" >'doproc.c' <<'END_OF_FILE'
  494. X/* @(#)doproc.c        (c) copyright    10/18/86 (Dan Heller) */
  495. X
  496. X/* do main panel item procedures */
  497. X#include "mush.h"
  498. X
  499. respond_mail(item, value, event)
  500. Panel_item item;
  501. int value;
  502. struct inputevent *event;
  503. X{
  504. X    char buf[80];
  505. X
  506. X    if (value == 4)
  507. X    return help(panel_sw->ts_windowfd, "respond", tool_help);
  508. X    if (ison(glob_flags, IS_GETTING)) {
  509. X    print("Finish editing current message first");
  510. X    return;
  511. X    }
  512. X    if (!msg_cnt) {
  513. X    print("No messages to respond to.\n");
  514. X    return;
  515. X    }
  516. X    print("Responding to message %d", current_msg+1);
  517. X    if (event && event->ie_code == MS_LEFT)
  518. X    value = 0;
  519. X    (void) sprintf(buf, "%s %s %d",
  520. X    (value == 2 || value == 3)? "replyall" : "replysender",
  521. X    (value == 1 || value == 3)? "-i": NO_STRING, current_msg+1);
  522. X    (void) cmd_line(buf, msg_list);
  523. X}
  524. X
  525. X/* following macro is for the next two procedures */
  526. X#define hdr_item (item == sub_hdr_item[0] || item == sub_hdr_item[1] || \
  527. X                  item == sub_hdr_item[2] || item == sub_hdr_item[3] || \
  528. X                  item == sub_hdr_item[4] || item == sub_hdr_item[5])
  529. X
  530. delete_mail(item, value, event)
  531. register Panel_item item;
  532. int value;
  533. register struct inputevent *event;
  534. X{
  535. X    int val = value; /* save cuz we reset value immediately */
  536. X    u_long bang = ison(glob_flags, IGN_BANG);
  537. X    char buf[128];
  538. X
  539. X    panel_set(item, PANEL_VALUE, 0, 0);
  540. X    if (hdr_item && event->ie_code != MS_LEFT || val == 2)
  541. X    return help(panel_sw->ts_windowfd, "delete", tool_help);
  542. X    /* delete current message */
  543. X    print(sprintf(buf, "%sdelete %s",
  544. X    ((event->ie_code == MS_LEFT || val == 0)? "" : "un"),
  545. X    panel_get_value(msg_num_item)));
  546. X    turnon(glob_flags, IGN_BANG);
  547. X    (void) cmd_line(buf, msg_list);
  548. X    if (!bang)
  549. X    turnoff(glob_flags, IGN_BANG);
  550. X}
  551. X
  552. read_mail(item, value, event)
  553. register Panel_item item;
  554. register int value;
  555. register struct inputevent *event;
  556. X{
  557. X    register int this_msg = current_msg;
  558. X
  559. X    /* check "event" in case we were called from select.c
  560. X     * in which case event would be NULL
  561. X     */
  562. X    if (event && event->ie_code == MS_RIGHT &&
  563. X        item && (item == read_item && value ||
  564. X    (item == sub_hdr_item[0] || item == sub_hdr_item[1])))
  565. X    return help(panel_sw->ts_windowfd, "next", tool_help);
  566. X    if (item && (item == sub_hdr_item[4] || item == sub_hdr_item[5]))
  567. X    return help(panel_sw->ts_windowfd, "msg_menu", tool_help);
  568. X    if (!msg_cnt) {
  569. X    print ("No Mail.");
  570. X    return -1;
  571. X    }
  572. X    if (item && item == read_item || ison(msg[current_msg].m_flags, DELETE))
  573. X    (void) next_msg();
  574. X    if (this_msg != current_msg || ison(msg[current_msg].m_flags, UNREAD) ||
  575. X        (current_msg < n_array[0] || current_msg > n_array[screen])) {
  576. X    set_isread(current_msg);
  577. X    (void) do_hdrs(0, DUBL_NULL, NULL);
  578. X    }
  579. X    if (isoff(msg[current_msg].m_flags, DELETE))
  580. X    display_msg(current_msg, (long)0);
  581. X    return -1;
  582. X}
  583. X
  584. X/* the panel button that says "filename" and "directory", etc... text item */
  585. file_dir(item, event)
  586. Panel_item item;
  587. struct inputevent *event;
  588. X{
  589. X    register char *p;
  590. X    u_long bang = ison(glob_flags, IGN_BANG);
  591. X    char buf[128], *which = panel_get(item, PANEL_LABEL_STRING);
  592. X
  593. X    if (!strcmp(which, "folder:"))
  594. X    if (event->ie_code == '\n' || event->ie_code == '\r')
  595. X        (void) sprintf(buf, "folder %s", panel_get_value(item));
  596. X    else
  597. X        (void) sprintf(buf, "folder ! %s", panel_get_value(item));
  598. X
  599. X    else if (!strcmp(which, "directory:"))
  600. X    (void) sprintf(buf, "cd %s", panel_get_value(item));
  601. X
  602. X    else if (!msg_cnt)
  603. X    print("No messages to save");
  604. X
  605. X    else if (!strcmp(which, "filename:")) {
  606. X    int x = 1;
  607. X    register char *b = buf;
  608. X    if (event->ie_code == '\n' || event->ie_code == '\r')
  609. X        b += Strcpy(buf, "save  ");
  610. X    else
  611. X        b += Strcpy(buf, "write ");
  612. X    if ((p = panel_get_value(msg_num_item)) && *p)
  613. X        b += Strcpy(b, p);
  614. X    else
  615. X        b += strlen(sprintf(b, "%d", current_msg+1));
  616. X    *b++ = ' ', *b = 0;
  617. X    if (!(p = panel_get_value(item)) || !*p &&
  618. X        (!(p = do_set(set_options, "mbox")) || !*p))
  619. X        p = DEF_MBOX;
  620. X    print(buf), print_more("in %s?", p); /* prompt before adding to cmd */
  621. X    (void) strcpy(b, p); /* now add to command */
  622. X    if ((x = confirm(print_sw->ts_windowfd)) != 'y' && x != MS_LEFT) {
  623. X        print("Message not saved");
  624. X        return;
  625. X    }
  626. X    }
  627. X    turnon(glob_flags, IGN_BANG);
  628. X    (void) cmd_line(buf, msg_list);
  629. X    if (!bang)
  630. X    turnoff(glob_flags, IGN_BANG);
  631. X}
  632. X
  633. do_file_dir(item, value, event)
  634. Panel_item item;
  635. int value;
  636. struct inputevent *event;
  637. X{
  638. X    char buf[92];
  639. X    u_long bang = ison(glob_flags, IGN_BANG);
  640. X    int x; /* used for confirmation */
  641. X
  642. X    if (item == folder_item) {
  643. X    (void) strcpy(buf, "folder ");
  644. X    if (event->ie_code == MS_LEFT) {
  645. X        print("Current folder is: \"%s\"", mailfile);
  646. X        panel_set(file_item, PANEL_LABEL_STRING, "folder:", 0);
  647. X        panel_set(file_item, PANEL_MENU_CHOICE_STRINGS,
  648. X                "Change without updating current folder", 0, 0);
  649. X    } else {
  650. X        if (!value)
  651. X        (void) strcat(buf, "%");
  652. X        else if (value == 1)
  653. X        (void) strcat(buf, "&");
  654. X        else if (value == 2)
  655. X        (void) strcat(buf, "#");
  656. X        else {
  657. X        (void) sprintf(buf, "folder %s",
  658. X                  panel_get(item, PANEL_CHOICE_STRING, value));
  659. X        if (!strcmp(buf+7, "Help"))
  660. X            return help(panel_sw->ts_windowfd, "folder", tool_help);
  661. X        }
  662. X    }
  663. X    } else if (item == cd_item) {
  664. X    (void) strcpy(buf, "cd ");
  665. X    if (event->ie_code == MS_LEFT || !value) {
  666. X        panel_set(file_item, PANEL_LABEL_STRING, "directory:", 0);
  667. X        panel_set(file_item, PANEL_MENU_CHOICE_STRINGS,
  668. X                "Change to specified directory", 0, 0);
  669. X    } else if (value == 1)
  670. X        (void) strcat(buf, "~");
  671. X    else if (value == 2)
  672. X        (void) strcat(buf, "+");
  673. X    else
  674. X        return help(panel_sw->ts_windowfd, "chdir", tool_help);
  675. X    } else if (item == save_item) {
  676. X    (void) strcpy(buf, "save ");
  677. X    if (event->ie_code == MS_LEFT)
  678. X        if (!strcmp("filename:", panel_get(file_item,PANEL_LABEL_STRING))) {
  679. X        event->ie_code = '\n';  /* let file_dir think it got a \n */
  680. X        return file_dir(file_item, event);
  681. X        } else {
  682. X        panel_set(file_item, PANEL_LABEL_STRING, "filename:", 0);
  683. X        panel_set(file_item, PANEL_MENU_CHOICE_STRINGS,
  684. X            "Save message WITHOUT headers", 0,0);
  685. X        print("Type in Main Panel Window a filename to save message");
  686. X        return;
  687. X        }
  688. X    else if (value <= 1) {
  689. X        register char *p = panel_get_value(file_item);
  690. X        register char *p2 = panel_get_value(msg_num_item);
  691. X        if ((!p || !*p) && (!(p = do_set(set_options, "mbox")) || !*p))
  692. X        p = DEF_MBOX;
  693. X        print("Save in %s? ", p);
  694. X        if ((x = confirm(panel_sw->ts_windowfd)) != 'y' && x != MS_LEFT) {
  695. X        print("Message not saved");
  696. X        return;
  697. X        }
  698. X        if (p2 && *p2) {
  699. X        (void) strcat(buf, p2);
  700. X        panel_set(msg_num_item, PANEL_VALUE, NO_STRING, 0);
  701. X        (void) strcat(buf, " ");
  702. X        }
  703. X        (void) strcat(buf, p);
  704. X    } else {
  705. X        (void) sprintf(buf, "save %s",
  706. X        panel_get(item, PANEL_CHOICE_STRING, value));
  707. X        if (!strcmp(buf+5, "Help"))
  708. X        return help(panel_sw->ts_windowfd, "save", tool_help);
  709. X    }
  710. X    }
  711. X    turnon(glob_flags, IGN_BANG);
  712. X    (void) cmd_line(buf, msg_list);
  713. X    if (!bang)
  714. X    turnoff(glob_flags, IGN_BANG);
  715. X    panel_set(item, PANEL_VALUE, NO_STRING, 0); /* remove last value */
  716. X}
  717. X
  718. text_done(item, event)
  719. Panel_item item;
  720. struct inputevent *event;
  721. X{
  722. X    char opt[30], buf[82], cmd[82];
  723. X    register char *p;
  724. X    u_long bang = ison(glob_flags, IGN_BANG);
  725. X    Panel_item which = NO_ITEM;
  726. X    int set_it;
  727. X
  728. X    if ((event->ie_code == '\n' || event->ie_code == '\r') && 
  729. X                 *strcpy(buf, panel_get_value(item))) {
  730. X    (void) strcpy(opt, panel_get(item, PANEL_LABEL_STRING));
  731. X    set_it = (*opt == 'S');
  732. X    if (!(p = index(opt, ' '))) {
  733. X        print("Hmmm... there seems to be a problem here.");
  734. X        return;
  735. X    }
  736. X    ++p;
  737. X    switch(lower(*p)) {
  738. X        case 'o':
  739. X        (void) sprintf(cmd, "%set %s", (set_it)? "s": "uns", buf);
  740. X        which = option_item;
  741. X        when 'i':
  742. X        (void) sprintf(cmd, "%sgnore %s", (set_it)? "i": "uni", buf);
  743. X        which = ignore_item;
  744. X        when 'a':
  745. X        (void) sprintf(cmd, "%slias %s", (set_it)? "a": "una", buf);
  746. X        which = alias_item;
  747. X        otherwise: print("HUH!? (%c)", *p); return;
  748. X    }
  749. X    turnon(glob_flags, IGN_BANG);
  750. X    (void) cmd_line(cmd, msg_list);
  751. X    if (!bang)
  752. X        turnoff(glob_flags, IGN_BANG);
  753. X    }
  754. X    panel_set(input_item, PANEL_VALUE, NO_STRING, 0); /* remove last value */
  755. X    panel_set(item, PANEL_SHOW_ITEM, FALSE, 0);
  756. X}
  757. X
  758. do_help(item, value, event)
  759. Panel_item item;
  760. register int value;
  761. struct inputevent *event;
  762. X{
  763. X    register char *p, *helpfile = tool_help;
  764. X    switch(value) {
  765. X    case 1: p = "help";
  766. X    when 2: p = "mouse";
  767. X    when 3: p = "windows";
  768. X    when 4: p = "function keys";
  769. X    when 5: p = "hdr_format", helpfile = cmd_help;
  770. X    when 6: p = "msg_list", helpfile = cmd_help;
  771. X    otherwise: p = "general";
  772. X    }
  773. X    (void) help(panel_sw->ts_windowfd, p, helpfile);
  774. X}
  775. X
  776. toolquit(item, value, event)
  777. Panel_item item;
  778. int value;
  779. struct inputevent *event;
  780. X{
  781. X    register int which;
  782. X
  783. X    if (!value || event->ie_code == MS_LEFT) {
  784. X    do_update(NO_ITEM, 0, NO_EVENT);
  785. X    turnoff(glob_flags, NEW_MAIL);
  786. X    mail_status(0); /* lower flag (if up) print current num of msgs */
  787. X    wmgr_changestate (tool->tl_windowfd, rootfd, TRUE);
  788. X    wmgr_changelevel (tool->tl_windowfd, parentfd, TRUE);
  789. X    return;
  790. X    } else if (value == 2) {
  791. X    (void) help(panel_sw->ts_windowfd, "quit", tool_help);
  792. X    return;
  793. X    }
  794. X    print("Left updates changes. Middle does not. Right aborts quit.");
  795. X    if ((which = confirm(panel_sw->ts_windowfd)) == MS_RIGHT) {
  796. X    print("Quit aborted.");
  797. X    return;
  798. X    }
  799. X    abort_mail(NO_ITEM, 0);
  800. X    if (which == MS_LEFT)
  801. X    lock_cursors(), copyback();
  802. X    else
  803. X    print("Bye bye");
  804. X    cleanup(0);
  805. X}
  806. X
  807. do_lpr(item, value, event)
  808. Panel_item item;
  809. int value;
  810. struct inputevent *event;
  811. X{
  812. X    char buf[128];
  813. X
  814. X    if (event && (event->ie_code == MS_LEFT || value == 1)) {
  815. X    print("Sending message %d to printer...", current_msg+1);
  816. X    (void) strcpy(buf, "lpr ");
  817. X    if (value)
  818. X        (void) sprintf(buf, "lpr \"%s\"", panel_get_value(msg_num_item));
  819. X    lock_cursors();
  820. X    (void) cmd_line(buf, msg_list);
  821. X    unlock_cursors();
  822. X    } else
  823. X    (void) help(panel_sw->ts_windowfd, "printer", tool_help);
  824. X}
  825. X
  826. do_clear()
  827. X{
  828. X    /* actions that clears window indicates user wants to quit getting opts */
  829. X    if (msg_pix)
  830. X    pr_destroy(msg_pix), msg_pix = (struct pixrect *)NULL;
  831. X    if (getting_opts)
  832. X    getting_opts = 0, unlock_cursors();
  833. X    pw_writebackground(msg_win, 0,0, msg_rect.r_width,msg_rect.r_height,
  834. X               PIX_CLR);
  835. X    txt.x = 5, txt.y = l_height(curfont) - 1;
  836. X}
  837. X
  838. do_update(item, value, event)
  839. Panel_item item;
  840. register int value;
  841. struct inputevent *event;
  842. X{
  843. X    char *argv[2];
  844. X    if (event && event->ie_code != MS_LEFT)
  845. X    return help(panel_sw->ts_windowfd, "update", tool_help);
  846. X    argv[0] = "update";
  847. X    argv[1] = NULL;
  848. X    (void) folder(0, argv, NULL);
  849. X}
  850. X
  851. X/* panel selction button to send a letter.
  852. X * add a CR if necessary, and finish up letter
  853. X */
  854. do_send(item, value, event)
  855. Panel_item item;
  856. register int value;
  857. register struct inputevent *event;
  858. X{
  859. X    if (event->ie_code != MS_LEFT)
  860. X    return help(panel_sw->ts_windowfd, "send", tool_help);
  861. X    if (txt.x > 5) {
  862. X    type_cursor(PIX_CLR);
  863. X    add_to_letter(rite('\n')); /* if line isn't complete, flush it */
  864. X    }
  865. X    finish_up_letter();
  866. X}
  867. X
  868. do_edit(item, value, event)
  869. Panel_item item;
  870. register int value;
  871. register struct inputevent *event;
  872. X{
  873. X    char buf[4];
  874. X    if (event->ie_code != MS_LEFT)
  875. X    return help(panel_sw->ts_windowfd, "edit", tool_help);
  876. X    if (txt.x > 5)
  877. X    add_to_letter(rite('\n')); /* flush line for him */
  878. X    add_to_letter(sprintf(buf, "%cv", *escape));
  879. X}
  880. X
  881. do_compose(item, value, event)
  882. Panel_item item;
  883. register int value;
  884. struct inputevent *event;
  885. X{
  886. X    if (event && event->ie_code != MS_LEFT)
  887. X    return help(panel_sw->ts_windowfd, "compose", tool_help);
  888. X    print("Composing letter.");
  889. X    win_setcursor(msg_sw->ts_windowfd, &write_cursor);
  890. X    clear_msg_list(msg_list);
  891. X    do_mail(0, DUBL_NULL, msg_list);
  892. X}
  893. X
  894. change_font(item, value, event)
  895. Panel_item item;
  896. register int value;
  897. struct inputevent event;
  898. X{
  899. X    if (ison(glob_flags, IS_GETTING))
  900. X    type_cursor(PIX_XOR);
  901. X    curfont = value % total_fonts;
  902. X    print("New font: %s\n",
  903. X        (!curfont)? "Normal": (curfont == 1)? "Small": "Large");
  904. X    if (ison(glob_flags, IS_GETTING))
  905. X    type_cursor(PIX_XOR);
  906. X    crt = msg_rect.r_height / l_height(curfont);
  907. X}
  908. END_OF_FILE
  909. if test 12080 -ne `wc -c <'doproc.c'`; then
  910.     echo shar: \"'doproc.c'\" unpacked with wrong size!
  911. fi
  912. # end of 'doproc.c'
  913. fi
  914. if test -f 'main.c' -a "${1}" != "-c" ; then 
  915.   echo shar: Will not clobber existing file \"'main.c'\"
  916. else
  917. echo shar: Extracting \"'main.c'\" \(11131 characters\)
  918. sed "s/^X//" >'main.c' <<'END_OF_FILE'
  919. X/* @(#)main.c    (c) copyright 10/18/86 (Dan Heller) */
  920. X
  921. X#include "mush.h"
  922. X
  923. static char *usage_str =
  924. X#ifdef SUNTOOL 
  925. X    "usage: %s [-C] [-i] [-f [folder] ] [-v] [-S] [-t] [-s subject] [users]\n";
  926. X#else
  927. X#ifdef CURSES
  928. X    "usage: %s [-C] [-i] [-f [folder] ] [-v] [-S] [-s subject] [user list]\n";
  929. X#else
  930. X    "usage: %s [-i] [-f [folder] ] [-v] [-S] [-s subject] [user list]\n";
  931. X#endif /* CURSES */
  932. X#endif /* SUNTOOL */
  933. X
  934. X#if defined(sun) && defined(M_DEBUG)
  935. cpu()
  936. X{
  937. X    print("CPU time limit exceeded!\n");
  938. X}
  939. X#endif /* sun && DEBUG */
  940. X
  941. X/*ARGSUSED*/   /* we ignore envp */
  942. main(argc, argv)
  943. char **argv;
  944. X{
  945. X    u_long         flg = NO_FLG;
  946. X    int            n, source_rc = TRUE;
  947. X    char         f_flags[10], buf[256], *Cc = NULL, *Subj = NULL;
  948. X    register char  *p;
  949. X    char      **args;
  950. X
  951. X    if (prog_name = rindex(*argv, '/'))
  952. X    prog_name++;
  953. X    else
  954. X    prog_name = *argv;
  955. X
  956. X    (void) signal(SIGBUS,  bus_n_seg);
  957. X    (void) signal(SIGSEGV, bus_n_seg);
  958. X
  959. X    f_flags[0] = 0;
  960. X    mailfile = "";
  961. X
  962. X#if defined(sun) && defined(M_DEBUG)
  963. X    (void) signal(SIGXCPU, cpu);
  964. X
  965. X    if (p = getenv("MALLOC_DEBUG"))
  966. X    malloc_debug(atoi(p));
  967. X    else
  968. X    malloc_debug(0);
  969. X#endif /* sun && debug */
  970. X
  971. X    if (!isatty(0))
  972. X    turnon(glob_flags, REDIRECT);
  973. X    f_flags[0] = '\0';
  974. X
  975. X    n = 0; /* don't ignore no such file or directory */
  976. X    p = getpath(COMMAND_HELP, &n);
  977. X
  978. X    if (n) {
  979. X    fprintf(stderr, "Warning: can't read %s: %s\n", COMMAND_HELP, p);
  980. X    cmd_help = "cmd_help";
  981. X    } else
  982. X    strdup(cmd_help, p);
  983. X
  984. X    init(); /* must be done before checking mail since "login" is set here */
  985. X    strdup(spoolfile, sprintf(buf, "%s/%s", MAILDIR, login));
  986. X
  987. X    n = FALSE;
  988. X#ifdef SUNTOOL
  989. X    if (n = istool = strlen(prog_name) > 3 &&
  990. X         !strcmp(prog_name+strlen(prog_name)-4, "tool"))
  991. X    turnon(glob_flags, DO_SHELL);
  992. X#endif /* SUNTOOL */
  993. X
  994. X    /*
  995. X     * preparse the command line to determine whether or not we're going
  996. X     * to bail out after checking that the user has no mail.  Also, check
  997. X     * to see if we're going to run a tool because it must be built first.
  998. X     */
  999. X    if (!istool && argc > 1) {
  1000. X    for (args = argv+1; *args && args[0][0] == '-'; args++)
  1001. X        switch (args[0][1]) {
  1002. X#ifdef SUNTOOL
  1003. X        case 'T' :
  1004. X            if (args[1])
  1005. X            args++;
  1006. X        case 't' :
  1007. X            istool = 1;
  1008. X            n = TRUE;
  1009. X            turnon(glob_flags, DO_SHELL);
  1010. X            break;
  1011. X#endif /* SUNTOOL */
  1012. X        case 'S' : turnon(glob_flags, DO_SHELL);
  1013. X        case 'f' :
  1014. X        case 'u' :
  1015. X            if (args[1])
  1016. X            args++;
  1017. X            n = TRUE;
  1018. X            break;
  1019. X        case 'c' :
  1020. X        case 's' :
  1021. X        case '1' :
  1022. X        case '2' :
  1023. X            if (args[1])
  1024. X            args++;
  1025. X        default : ;
  1026. X        }
  1027. X    if (*args) {  /* unused args indicates sending mail to someone */
  1028. X        n = TRUE;
  1029. X        if (!istool)
  1030. X        turnon(glob_flags, IS_SENDING);
  1031. X    }
  1032. X    }
  1033. X
  1034. X#ifdef SUNTOOL
  1035. X    /* even if not running tool mode parse all potential suntools args out */
  1036. X    args = DUBL_NULL;
  1037. X    tool_parse_all(&argc, argv, &args, prog_name);
  1038. X#endif /* SUNTOOL */
  1039. X
  1040. X    /* check for any mail at all and exit if we're not continuing */
  1041. X    if (!n) {
  1042. X    struct stat statb;
  1043. X    if (stat(spoolfile, &statb) || statb.st_size == 0) {
  1044. X        printf("No mail for %s.\n", login);
  1045. X        exit(0);
  1046. X    }
  1047. X    }
  1048. X
  1049. X    for (++argv; *argv && **argv == '-'; argv++)
  1050. X    switch (argv[0][1]) {
  1051. X        case 'e':
  1052. X        /*
  1053. X         * don't set tty modes -- e.g. echo and cbreak modes aren't
  1054. X         * changed.
  1055. X         */
  1056. X        turnon(glob_flags, ECHO_FLAG);
  1057. X#ifdef CURSES
  1058. X        when 'C':
  1059. X        /* don't init curses -- don't even set iscurses.   */
  1060. X        if (istool) {
  1061. X            puts("-C: You are already running in tool mode");
  1062. X            turnoff(glob_flags, PRE_CURSES);
  1063. X        } else if (hdrs_only)
  1064. X            puts("headers only: ignoring -C flag");
  1065. X        else
  1066. X            turnon(glob_flags, PRE_CURSES);
  1067. X#endif /* CURSES */
  1068. X        when 'N':
  1069. X        (void) strcat(f_flags, "-N ");
  1070. X        when 'r':
  1071. X        (void) strcat(f_flags, "-r "); /* folder() argument */
  1072. X        when 'H':
  1073. X        if (istool) {
  1074. X            puts("running in tool-mode; -H option ignored.");
  1075. X            break;
  1076. X        }
  1077. X        turnoff(glob_flags, PRE_CURSES);
  1078. X        if (*(hdrs_only = (*argv)+2) != ':')
  1079. X            hdrs_only = ":a";
  1080. X        (void) strcat(f_flags, "-N -r "); /* read only cuz no updates */
  1081. X        when 'i':
  1082. X        /* force interactive even if !isatty(0) */
  1083. X        turnoff(glob_flags, REDIRECT);
  1084. X        when 'u': /* specify a user's mailbox */
  1085. X        if (*mailfile)
  1086. X            puts("You can't specify more than one mailbox"), exit(1);
  1087. X        strdup(mailfile, sprintf(buf, "%s/%s",
  1088. X                   MAILDIR, (argv[1])? argv[1] : "root"));
  1089. X        if (argv[1])
  1090. X            ++argv;
  1091. X        when 'f':
  1092. X        if (*mailfile)
  1093. X            puts("You can't specify more than one mailbox"), exit(1);
  1094. X        if (argv[1])
  1095. X            strdup(mailfile, *++argv);
  1096. X        else
  1097. X            strdup(mailfile, "&");
  1098. X        when '1':
  1099. X        if (argv[1])
  1100. X            strdup(cmd_help, *++argv);
  1101. X        else
  1102. X            puts("-1 \"filename\""), exit(1);
  1103. X#ifdef SUNTOOL
  1104. X        when '2':
  1105. X        if (argv[1])
  1106. X            strdup(tool_help, *++argv);
  1107. X        else
  1108. X            puts("-2 \"filename\""), exit(1);
  1109. X#endif /* SUNTOOL */
  1110. X        when 's':
  1111. X        if (istool)
  1112. X            puts("bad option when run as a tool"), exit(1);
  1113. X        else if (argv[1])
  1114. X            Subj = *++argv;
  1115. X        else
  1116. X            puts("-s \"subject\""), exit(1);
  1117. X        when 'c':
  1118. X        if (istool)
  1119. X            puts("bad option when run as a tool"), exit(1);
  1120. X        else if (argv[1])
  1121. X            Cc = *++argv;
  1122. X        else
  1123. X            puts("-c \"cc list\""), exit(1);
  1124. X        break;
  1125. X#ifdef VERBOSE_ARG
  1126. X        case 'v':
  1127. X        if (istool)
  1128. X            puts("bad option when run as a tool"), exit(1);
  1129. X        turnon(flg, VERBOSE);
  1130. X        break;
  1131. X#endif /* VERBOSE_ARG */
  1132. X#ifdef SUNTOOL
  1133. X            case 'T':
  1134. X        if ((time_out = atoi(*argv)) <= 29)
  1135. X            time_out = 30;
  1136. X        /* -T implies -t */
  1137. X        case 't': istool = 1;
  1138. X#endif /* SUNTOOL */
  1139. X        case 'S': turnon(glob_flags, DO_SHELL);
  1140. X        when 'n': source_rc = FALSE;
  1141. X        when 'd': debug = 1;
  1142. X        otherwise:
  1143. X        print("%s: unknown option: `%c'\n", prog_name,
  1144. X            argv[0][1]? argv[0][1] : '-');
  1145. X        print(usage_str, prog_name);
  1146. X    }
  1147. X
  1148. X    if (source_rc) {
  1149. X    (void) cmd_line(sprintf(buf, "source %s", DEFAULT_RC), msg_list);
  1150. X    (void) source(0, DUBL_NULL);
  1151. X    }
  1152. X
  1153. X    set_cwd();  /* call _after_ sourcing files */
  1154. X
  1155. X#ifdef SUNTOOL
  1156. X    if (istool)
  1157. X    if (ison(glob_flags, REDIRECT))
  1158. X        puts("You can't redirect input to a tool."), exit(1);
  1159. X    else
  1160. X        make_tool(args), turnon(glob_flags, DO_SHELL);
  1161. X#endif /* SUNTOOL */
  1162. X
  1163. X    /* now we're ready for I/O */
  1164. X    if (isoff(glob_flags, REDIRECT)) {
  1165. X    /* make sure we can always recover from no echo mode */
  1166. X    (void) signal(SIGINT, catch);
  1167. X    (void) signal(SIGQUIT, catch);
  1168. X    if (istool)
  1169. X        turnon(glob_flags, ECHO_FLAG);
  1170. X    savetty();
  1171. X#ifdef TIOCGLTC
  1172. X    if (isatty(0) && ioctl(0, TIOCGLTC, <chars))
  1173. X        error("TIOCGLTC");
  1174. X#endif /* TIOCGLTC */
  1175. X#ifdef SIGCONT
  1176. X    (void) signal(SIGTSTP, stop_start); /* this will take care of SIGCONT */
  1177. X#endif /* SIGCONT */
  1178. X    /* echo_off() checks to see if echo_flg is set, so don't worry */
  1179. X    echo_off();
  1180. X    }
  1181. X
  1182. X    if (!istool && *argv) { /* we could check IS_SENDING */
  1183. X    char recipients[BUFSIZ];
  1184. X    (void) argv_to_string(recipients, argv);
  1185. X    fix_up_addr(recipients);
  1186. X    if (Cc && *Cc)
  1187. X        fix_up_addr(Cc);
  1188. X    /* prompt for subject and Cc list, but not "To: "
  1189. X     * mail_someone() already takes care of redirection.
  1190. X     * if -s or -c options are given, they will be passed.
  1191. X     */
  1192. X    if (do_set(set_options, "ask"))
  1193. X        turnon(flg, NEW_SUBJECT);
  1194. X    if (do_set(set_options, "autosign"))
  1195. X        turnon(flg, SIGN);
  1196. X    if (do_set(set_options, "autoedit"))
  1197. X        turnon(flg, EDIT);
  1198. X    if (do_set(set_options, "verbose"))
  1199. X        turnon(flg, VERBOSE);
  1200. X    if (do_set(set_options, "fortune"))
  1201. X        turnon(flg, DO_FORTUNE);
  1202. X    /* set now in case user is not running shell, but is running debug */
  1203. X    (void) signal(SIGCHLD, sigchldcatcher);
  1204. X    if (!setjmp(jmpbuf))
  1205. X        (void) mail_someone(recipients, Subj, Cc, flg, NULL);
  1206. X    /* do shell set from above: "mush -S user" perhaps */
  1207. X    if (isoff(glob_flags, DO_SHELL) && !*mailfile) {
  1208. X        if (isoff(glob_flags, REDIRECT))
  1209. X        echo_on();
  1210. X        exit(0);
  1211. X    }
  1212. X    }
  1213. X    turnoff(glob_flags, IS_SENDING); /* no longer sending mail; running shell */
  1214. X
  1215. X    if (ison(glob_flags, REDIRECT)) {
  1216. X    puts("You can't redirect input unless you're sending mail.");
  1217. X    puts("If you want to run a shell with redirection, use \"-i\"");
  1218. X    cleanup(0);
  1219. X    }
  1220. X    if (!*mailfile) {
  1221. X    strdup(mailfile, spoolfile);
  1222. X    if (!mail_size() && isoff(glob_flags, DO_SHELL)) {
  1223. X        /* we know it's not the spool file here */
  1224. X        printf("No mail in %s.\n", mailfile);
  1225. X        echo_on(), exit(0);
  1226. X    }
  1227. X    }
  1228. X
  1229. X    if (!hdrs_only) {
  1230. X    /* catch will test DO_SHELL and try to longjmp if set.  this is a
  1231. X     * transition state from no-shell to do-shell to ignore sigs to
  1232. X     * avoid a longjmp botch.  Note setjmp isn't called until do_loop().
  1233. X     */
  1234. X    turnon(glob_flags, IGN_SIGS);
  1235. X#ifdef CURSES
  1236. X    if (ison(glob_flags, PRE_CURSES))
  1237. X        (void) curses_init(0, DUBL_NULL);
  1238. X    turnoff(glob_flags, PRE_CURSES);
  1239. X#endif /* CURSES */
  1240. X    }
  1241. X
  1242. X    /* find a free tmpfile */
  1243. X    if (!(p = do_set(set_options, "home")) || !*p)
  1244. alted:
  1245. X    p = ALTERNATE_HOME;
  1246. X    flg = getpid();
  1247. X    while (!Access(sprintf(tempfile, "%s/.%s%d", p, prog_name, flg++), F_OK))
  1248. X    ;
  1249. X    /* just create the file, make sure it's empty.  It'll close later and
  1250. X     * be reopened for reading only.
  1251. X     */
  1252. X    {
  1253. X    int omask = umask(077);
  1254. X    tmpf = fopen(tempfile, "w");
  1255. X    (void) umask(omask);
  1256. X    if (!tmpf) {
  1257. X        if (p != ALTERNATE_HOME)
  1258. X        goto alted;
  1259. X        error("Can't create tempfile %s", tempfile);
  1260. X        cleanup(0);
  1261. X    }
  1262. X    }
  1263. X
  1264. X    /* do pseudo-intelligent stuff with certain signals */
  1265. X    (void) signal(SIGINT,  catch);
  1266. X    (void) signal(SIGQUIT, catch);
  1267. X    (void) signal(SIGHUP,  catch);
  1268. X
  1269. X    if (!hdrs_only && !istool && !do_set(set_options, "quiet"))
  1270. X    printf("%s: Type '?' for help.\n", VERSION);
  1271. X
  1272. X    (void) sprintf(buf, "folder %s %s", f_flags, mailfile);
  1273. X    if (argv = make_command(buf, TRPL_NULL, &argc)) {
  1274. X    if (folder(argc, argv, NULL) == -1 && isoff(glob_flags, DO_SHELL))
  1275. X        turnoff(glob_flags, IGN_SIGS), cleanup(0);
  1276. X    free_vec(argv);
  1277. X    }
  1278. X
  1279. X    if (hdrs_only) {
  1280. X    (void) sprintf(buf, "headers %s", hdrs_only);
  1281. X    if (argv = make_command(buf, TRPL_NULL, &argc))
  1282. X        (void) do_hdrs(argc, argv, NULL);
  1283. X    cleanup(0);
  1284. X    }
  1285. X
  1286. X    turnon(glob_flags, DO_SHELL);
  1287. X    if (istool && msg_cnt)
  1288. X    set_isread(current_msg);
  1289. X
  1290. X#ifdef SUNTOOL
  1291. X    if (istool) {
  1292. X    n = 0;
  1293. X    p = getpath(TOOL_HELP, &n);
  1294. X    if (n) {
  1295. X        fprintf(stderr, "Warning: can't read %s: %s\n", TOOL_HELP, p);
  1296. X        tool_help = "tool_help";
  1297. X    } else
  1298. X        strdup(tool_help, p);
  1299. X    if (time_out < 30)
  1300. X        time_out = 60;
  1301. X    turnoff(glob_flags, IGN_SIGS);
  1302. X    (void) do_hdrs(0, DUBL_NULL, NULL);
  1303. X    timerclear(&(mail_timer.it_interval));
  1304. X    timerclear(&(mail_timer.it_value));
  1305. X    mail_timer.it_value.tv_sec = time_out;
  1306. X    setitimer(ITIMER_REAL, &mail_timer, NULL);
  1307. X    (void) signal(SIGALRM, check_new_mail);
  1308. X    unlock_cursors();
  1309. X    while (!(tool->tl_flags & TOOL_DONE))
  1310. X        tool_select(tool, 1);
  1311. X    cleanup(0);
  1312. X    }
  1313. X#endif /* SUNTOOL */
  1314. X    do_loop();
  1315. X}
  1316. X
  1317. do_version()
  1318. X{
  1319. X    print("%s\n", VERSION);
  1320. X    return -1;
  1321. X}
  1322. X
  1323. X/* set the current working directory */
  1324. set_cwd()
  1325. X{
  1326. X    char buf[MAXPATHLEN], cwd[MAXPATHLEN];
  1327. X#ifndef SYSV
  1328. X    extern char *getwd();
  1329. X#else /* SYSV */
  1330. X    extern char *getcwd();
  1331. X#endif /* SYSV */
  1332. X
  1333. X#ifndef SYSV
  1334. X    if (getwd(cwd) == NULL)
  1335. X#else
  1336. X    if (getcwd(cwd, MAXPATHLEN) == NULL)
  1337. X#endif /* SYSV */
  1338. X    {
  1339. X    error("getcwd: %s", cwd);
  1340. X    (void) un_set(&set_options, "cwd");
  1341. X    } else
  1342. X    (void) cmd_line(sprintf(buf, "set cwd=\"%s\"", cwd), msg_list);
  1343. X}
  1344. END_OF_FILE
  1345. if test 11131 -ne `wc -c <'main.c'`; then
  1346.     echo shar: \"'main.c'\" unpacked with wrong size!
  1347. fi
  1348. # end of 'main.c'
  1349. fi
  1350. if test -f 'viewopts.c' -a "${1}" != "-c" ; then 
  1351.   echo shar: Will not clobber existing file \"'viewopts.c'\"
  1352. else
  1353. echo shar: Extracting \"'viewopts.c'\" \(12631 characters\)
  1354. sed "s/^X//" >'viewopts.c' <<'END_OF_FILE'
  1355. X/* @(#)viewopts.c    (c) copyright    10/18/86 (Dan Heller) */
  1356. X
  1357. X#include "mush.h"
  1358. X
  1359. struct viewopts {
  1360. X    char *v_opt;
  1361. X    char *v_prompt;
  1362. X    int  v_usage;
  1363. X#define TOOL  01
  1364. X#define TEXT  02
  1365. X    char *v_description;
  1366. X};
  1367. X
  1368. X/*
  1369. X * struct contains the option, a prompt if it has a string value, whether
  1370. X * or not it applies to non suntools, line mode, or both, and a
  1371. X * string describing what the option does. If the prompt string starts
  1372. X * with a minus sign, then the value can be set without a value. This
  1373. X * is there to indicate to option_line to print a toggle (cycle) pixrect
  1374. X * and to print TRUE/FALSE telling whether the value is on or off regardless
  1375. X * of it's "string" value.
  1376. X */
  1377. struct viewopts viewopts[] = {
  1378. X    { "alwaysignore", NULL, TOOL | TEXT,
  1379. X      "alwaysignore the message headers on the 'ignored' list." },
  1380. X    { "ask", NULL, TOOL | TEXT,
  1381. X      "Prompts for a subject on outgoing mail." },
  1382. X    { "askcc", NULL, TOOL | TEXT,
  1383. X      "Ask for list of Carbon Copy recipients whenever sending mail.", },
  1384. X    { "autodelete", NULL, TOOL | TEXT,
  1385. X      "Automatically delete ALL READ messages whenever you update mail.", },
  1386. X    { "autoedit", NULL, TOOL | TEXT,
  1387. X      "Automatically enter editor whenever you REPLY to mail.", },
  1388. X    { "autoinclude", NULL, TOOL | TEXT,
  1389. X      "Include a copy of author's message each time you reply to mail." },
  1390. X    { "autoprint", NULL, TOOL | TEXT,
  1391. X      "Display the next message on the list when you delete a message." },
  1392. X    { "auto_route", NULL, TOOL | TEXT,
  1393. X      "Remove redundant uucp addresses when replying to messages." },
  1394. X    { "autosign", "-Filename", TOOL | TEXT,
  1395. X      "Add file (~/.signature if set but no value) at end of all letters." },
  1396. X    { "autosign2", "Address : Filename", TOOL | TEXT,
  1397. X      "signature to use for specific addresses. \"addr, ... : <signature>\"", },
  1398. X    { "cdpath", "Path", TEXT,
  1399. X      "Path to search for directories when the \"cd\" command is issued." },
  1400. X    { "crt", "Lines", TEXT,
  1401. X      "The number of lines a message must have for 'pager' to be invoked." },
  1402. X    { "dead", "Filename", TOOL | TEXT,
  1403. X      "The name of the file to store dead mail. ~/dead.letter by default." },
  1404. X    { "dot", NULL, TOOL | TEXT,
  1405. X      "allow \".\" on a line by itself to send letter." },
  1406. X    { "editor", "Editor name/path", TOOL | TEXT,
  1407. X      "editor to use by default. Default is evironment EDITOR or \"vi\"" },
  1408. X    { "escape", "Character", TOOL | TEXT,
  1409. X      "Escape character for extended editing commands. (default = ~)" },
  1410. X    { "folder", "Pathname", TOOL | TEXT,
  1411. X      "Full pathname to the directory where personal folders are kept." },
  1412. X    { "fortune", "-Flag", TOOL | TEXT,
  1413. X      "Add fortune to end of letters. Flag to \"fortune\" is optional" },
  1414. X    { "fortunates", "Users", TOOL | TEXT,
  1415. X      "Those who will receive fortunes if fortune is set (default: All)." },
  1416. X    { "hdr_format", "Format", TOOL | TEXT,
  1417. X      "Formatting string for headers. \"headers -?\" or help hdr_format" },
  1418. X    { "history", "Number", TEXT,
  1419. X      "How many commands to remember (like csh)." },
  1420. X    { "hold", NULL, TOOL | TEXT,
  1421. X      "Read but not deleted messages are saved in spool -- not mbox." },
  1422. X    { "ignore_bang", NULL, TEXT,
  1423. X      "Ignore '!' as a history reference. Otherwise, escape by: \\!" },
  1424. X    { "ignoreeof", "-Command", TEXT,
  1425. X      "Ignores ^D as exit, or (if set), execute \"command\"." },
  1426. X    { "indent_str", "String", TOOL | TEXT,
  1427. X      "String to offset included messages within your letter", },
  1428. X    { "in_reply_to", NULL, TOOL | TEXT,
  1429. X      "When responding to mail, add In-Reply-To: to message headers." },
  1430. X    { "keepsave", NULL, TOOL | TEXT,
  1431. X      "Prevents messages from being marked as `deleted' when you `save'." },
  1432. X    { "known_hosts", "Host list", TOOL | TEXT,
  1433. X      "List of hosts that your site is known to uucp mail to." },
  1434. X    { "lister", "Arguemnts", TOOL | TEXT,
  1435. X      "Arguments passed to the 'ls' command." },
  1436. X    { "mbox", "Filename", TOOL | TEXT,
  1437. X      "Filename to use instead of ~/mbox for default mailbox." },
  1438. X    { "metoo", NULL, TOOL | TEXT,
  1439. X      "When replying to mail, metoo preserves your name on mailing list." },
  1440. X    { "mil_time", NULL, TOOL | TEXT,
  1441. X      "24-hour military time format is used whenever a time is printed. " },
  1442. X    { "newline", "-Command", TEXT,
  1443. X      "Ignore RETURN. If set to a string, execute \"command\"" },
  1444. X    { "no_expand", NULL, TEXT | TOOL,
  1445. X      "Prevents expansion of Mush aliases in outgoing mail." },
  1446. X    { "no_hdr", NULL, TOOL | TEXT,
  1447. X      "If set, personalized headers are NOT inserted to outgoing mail." },
  1448. X    { "no_reverse", NULL, TOOL | TEXT,
  1449. X      "disables reverse video in curses mode -- uses \"bold\" in tool mode." },
  1450. X    { "nosave", NULL, TOOL | TEXT,
  1451. X      "prevents aborted mail from being saved in dead.letter" },
  1452. X    { "pager", "Program", TEXT,
  1453. X      "Program name to be used as a pager for messages longer than crt." },
  1454. X    { "pre_indent_str", "String", TEXT | TOOL,
  1455. X      "String to precede interpolated message text into message body." },
  1456. X    { "post_indent_str", "String", TEXT | TOOL,
  1457. X      "String to succeed interpolated message text into message body." },
  1458. X    { "print_cmd", "Program", TOOL | TEXT,
  1459. X      "Alternate program to use to send messages to the printer." },
  1460. X    { "printer", "Printer", TOOL | TEXT,
  1461. X      "Printer to send messages to. Default is environment PRINTER" },
  1462. X    { "prompt", "String", TEXT,
  1463. X      "Your prompt.  \"help prompt\" for more information." },
  1464. X    { "quiet", NULL, TEXT,
  1465. X      "Don't print the version number of Mush on startup." },
  1466. X    { "record", "Filename", TOOL | TEXT,
  1467. X      "Save all outgoing mail in specified filename" },
  1468. X    { "reply_to_hdr", "Headers", TOOL | TEXT,
  1469. X      "List of headers use to construct reply adresses from a message.", },
  1470. X    { "screen", "Number of Headers", TEXT,
  1471. X      "Number of headers to print in non-suntools (text) mode" },
  1472. X    { "screen_win", "Number of Headers", TOOL,
  1473. X      "Set the size of the header window for the tool mode only." },
  1474. X    { "show_deleted", NULL, TOOL | TEXT,
  1475. X      "Show deleted messages in headers listings (unused in curses mode)" },
  1476. X    { "show_hdrs", "Headers", TOOL | TEXT,
  1477. X      "When displaying a message, show list of \"headers\" only." },
  1478. X    { "sendmail", "Program", TOOL | TEXT,
  1479. X      "Program to use to deliver mail instead of using the default."},
  1480. X    { "sort", "-Option", TOOL | TEXT,
  1481. X      "Pre-sorting of messages on program startup (set to valid sort option)" },
  1482. X    { "squeeze", NULL, TOOL | TEXT,
  1483. X      "When reading messages, squeeze all blank lines into one." },
  1484. X    { "top", "Lines", TOOL | TEXT,
  1485. X      "Number of lines to print of a message for the 'top' command."  },
  1486. X    { "unix", NULL, TEXT,
  1487. X      "Non-mush commands are considered to be UNIX commands." },
  1488. X    { "verify", NULL, TEXT,
  1489. X      "Verify to send, re-edit, or abort letter after editing." },
  1490. X    { "visual", "Visual editor", TOOL | TEXT,
  1491. X      "Visual editor to use by default. \"editor\" is used if not set." },
  1492. X    { "warning", NULL, TOOL | TEXT,
  1493. X      "Print warning messages for non-fatal errors." },
  1494. X    { "wrap", NULL, TOOL | TEXT,
  1495. X      "After referencing last message, message pointer wraps to start." }
  1496. X};
  1497. X
  1498. X#define total_opts (sizeof viewopts / sizeof (struct viewopts))
  1499. X
  1500. X#ifdef SUNTOOL
  1501. X
  1502. static int start_cnt;
  1503. X
  1504. X#define twenty     5 + 20*l_width(DEFAULT)
  1505. X#define forty     5 + 40*l_width(DEFAULT)
  1506. X#define image_at(x,y,image) pw_rop(msg_win, x, y, 16, 16, PIX_SRC, image, 0,0)
  1507. X
  1508. X/* print in default text, but increment in large text segments */
  1509. view_options()
  1510. X{
  1511. X    if (msg_rect.r_height < 80) {
  1512. X    print("Window not big enough to display options.");
  1513. X    return;
  1514. X    }
  1515. X    do_clear();
  1516. X    getting_opts = 1, start_cnt = 0;
  1517. X    win_setcursor(msg_sw->ts_windowfd, &checkmark);
  1518. X    highlight(msg_win, txt.x, txt.y, LARGE,
  1519. X        "    : Toggle Value       : Description       : Menu (Help)");
  1520. X    image_at(txt.x +  2 * l_width(DEFAULT), txt.y - 12, &mouse_left);
  1521. X    image_at(txt.x + 25 * l_width(DEFAULT), txt.y - 12, &mouse_middle);
  1522. X    image_at(txt.x + 48 * l_width(DEFAULT), txt.y - 12, &mouse_right);
  1523. X
  1524. X    pw_vector(msg_win, 0, txt.y+6, msg_rect.r_width, txt.y+6, PIX_SRC, 1);
  1525. X    pw_vector(msg_win, 0, txt.y+8, msg_rect.r_width, txt.y+8, PIX_SRC, 1);
  1526. X
  1527. X    txt.y += 24;
  1528. X
  1529. X    pw_text(msg_win, 5,      txt.y, PIX_SRC, fonts[LARGE], "Option");
  1530. X    pw_text(msg_win, twenty, txt.y, PIX_SRC, fonts[LARGE], "On/Off");
  1531. X    pw_text(msg_win, forty,  txt.y, PIX_SRC, fonts[LARGE], "Values");
  1532. X
  1533. X    pw_vector(msg_win, 0, txt.y+6, msg_rect.r_width, txt.y+6, PIX_SRC, 1);
  1534. X    pw_vector(msg_win, 0, txt.y+8, msg_rect.r_width, txt.y+8, PIX_SRC, 1);
  1535. X
  1536. X    pw_text(msg_win, 59*l_width(DEFAULT),txt.y,PIX_SRC,fonts[LARGE],"Scroll:");
  1537. X    pw_rop(msg_win, 60*l_width(LARGE), txt.y-13,16,16,PIX_SRC, &dn_arrow,0,0);
  1538. X    pw_rop(msg_win, 60*l_width(LARGE)+20,txt.y-13,16,16,PIX_SRC, &up_arrow,0,0);
  1539. X
  1540. X    display_opts(0); /* create the pixrect and all that */
  1541. X}
  1542. X
  1543. display_opts(count)
  1544. register int count;
  1545. X{
  1546. X    register int total_displayable = (msg_rect.r_height - 60) / 20;
  1547. X
  1548. X    if (count < 0 && start_cnt + count < 0) {
  1549. X    print("At the beginning");
  1550. X    return;
  1551. X    } else if (count && start_cnt + count + total_displayable > total_opts) {
  1552. X    print("At the end");
  1553. X    return;
  1554. X    }
  1555. X    start_cnt += count;
  1556. X    if (!msg_pix) {
  1557. X    register int x = (total_opts+1) * 20;
  1558. X    if (x < msg_rect.r_height)
  1559. X        x = msg_rect.r_height;
  1560. X    if (!(msg_pix = mem_create(msg_rect.r_width, x, 1))) {
  1561. X        error("mem_create");
  1562. X        return;
  1563. X    }
  1564. X    pr_rop(msg_pix,0,0, msg_rect.r_width-1, x-1, PIX_CLR,0,0,0);
  1565. X    for (count = 0; count < total_opts; count++)
  1566. X        option_line(count);
  1567. X    }
  1568. X    pw_rop(msg_win, 0, 50, msg_rect.r_width - 1, msg_rect.r_height - 50,
  1569. X       PIX_SRC, msg_pix, 0, start_cnt * 20);
  1570. X}
  1571. X
  1572. void
  1573. toggle_opt(line)
  1574. X{
  1575. X    register char *p = viewopts[start_cnt+line].v_prompt;
  1576. X
  1577. X    if (do_set(set_options, viewopts[start_cnt+line].v_opt))
  1578. X    un_set(&set_options, viewopts[start_cnt+line].v_opt);
  1579. X    else {
  1580. X    if (p) {
  1581. X        txt.x = 5 + 40 * l_width(DEFAULT) +
  1582. X            (1 + strlen(p) - (*p=='-')) * l_width(DEFAULT);
  1583. X        txt.y = 50 + line*20 + l_height(curfont);
  1584. X    }
  1585. X    if (!p || *p == '-') {
  1586. X        register char *argv[2];
  1587. X        argv[0] = viewopts[start_cnt+line].v_opt;
  1588. X        argv[1] = NULL;
  1589. X        (void) add_option(&set_options, argv);
  1590. X    }
  1591. X    }
  1592. X    option_line(line);
  1593. X    display_opts(0);
  1594. X    if (txt.x > 5)
  1595. X    type_cursor(PIX_SRC);
  1596. X}
  1597. X
  1598. void
  1599. help_opt(line)
  1600. X{
  1601. X    print(viewopts[start_cnt+line].v_description);
  1602. X}
  1603. X
  1604. add_opt(p, line)
  1605. register char *p;
  1606. X{
  1607. X    char buf[80], **argv;
  1608. X    int argc;
  1609. X    u_long save_bang = ison(glob_flags, IGN_BANG);
  1610. X
  1611. X    (void) sprintf(buf, "set %s=\"%s\"", viewopts[start_cnt+line].v_opt, p);
  1612. X    turnon(glob_flags, IGN_BANG);
  1613. X    if (argv = make_command(buf, DUBL_NULL, &argc))
  1614. X    (void) do_command(argc, argv, msg_list);
  1615. X    if (!save_bang)
  1616. X    turnoff(glob_flags, IGN_BANG);
  1617. X    option_line(line); /* make sure new value is entered into database */
  1618. X}
  1619. X
  1620. option_line(count)
  1621. register int count;
  1622. X{
  1623. X    register char *p, *v = do_set(set_options, viewopts[start_cnt+count].v_opt);
  1624. X    struct pr_prpos win;
  1625. X
  1626. X    win.pr = msg_pix;
  1627. X    win.pos.y = (start_cnt + count) * 20 + 16;
  1628. X    win.pos.x = 5;
  1629. X
  1630. X    pf_text(win, PIX_SRC, fonts[DEFAULT], blank);
  1631. X    pf_text(win, PIX_SRC, fonts[DEFAULT], viewopts[start_cnt+count].v_opt);
  1632. X    win.pos.x = twenty+20;
  1633. X
  1634. X    if (!(p = viewopts[start_cnt+count].v_prompt) || *p == '-') {
  1635. X    pr_rop(msg_pix, twenty, win.pos.y-10, 16, 16, PIX_SRC, &cycle, 0, 0);
  1636. X    pf_text(win, PIX_SRC, fonts[DEFAULT], (v)? "TRUE  ": "FALSE");
  1637. X    win.pos.x++;
  1638. X    pf_text(win, PIX_SRC, fonts[DEFAULT], (v)? "TRUE  ": "FALSE");
  1639. X    }
  1640. X    if (p) {
  1641. X    if (*p == '-')
  1642. X        p++;
  1643. X    win.pos.x = forty;
  1644. X    /* heighlight */
  1645. X    pf_text(win, PIX_SRC, fonts[DEFAULT], p);
  1646. X    win.pos.x++;
  1647. X    pf_text(win, PIX_SRC, fonts[DEFAULT], p);
  1648. X        win.pos.x = forty + strlen(p) * l_width(DEFAULT);
  1649. X    pf_text(win, PIX_SRC, fonts[DEFAULT], ":");
  1650. X    if (v) {
  1651. X        win.pos.x += (2 * l_width(DEFAULT));
  1652. X        pf_text(win, PIX_SRC, fonts[DEFAULT], v);
  1653. X    }
  1654. X    }
  1655. X}
  1656. X
  1657. X#endif /* SUNTOOL */
  1658. X
  1659. X/*
  1660. X * return a string describing a variable.
  1661. X * parameters: count, str, buf.
  1662. X * If str != NULL, check str against ALL variables
  1663. X * in viewopts array.  The one that matches, set count to it and 
  1664. X * print up all the stuff from the viewopts[count] into the buffer
  1665. X * space in "buf" and return it.
  1666. X */
  1667. char *
  1668. variable_stuff(count, str, buf)
  1669. register char *str, buf[];
  1670. X{
  1671. X    if (str)
  1672. X    for (count = 0; count < total_opts; count++)
  1673. X        if (!strcmp(str, viewopts[count].v_opt))
  1674. X        break;
  1675. X    if (count >= total_opts) {
  1676. X    (void) sprintf(buf, "%s: Not a default %s variable.",
  1677. X               str? str : itoa(count), prog_name);
  1678. X    return NULL;
  1679. X    }
  1680. X    return sprintf(buf, "%s: %s",
  1681. X    viewopts[count].v_opt, viewopts[count].v_description);
  1682. X}
  1683. END_OF_FILE
  1684. if test 12631 -ne `wc -c <'viewopts.c'`; then
  1685.     echo shar: \"'viewopts.c'\" unpacked with wrong size!
  1686. fi
  1687. # end of 'viewopts.c'
  1688. fi
  1689. echo shar: End of archive 5 \(of 14\).
  1690. cp /dev/null ark5isdone
  1691. MISSING=""
  1692. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
  1693.     if test ! -f ark${I}isdone ; then
  1694.     MISSING="${MISSING} ${I}"
  1695.     fi
  1696. done
  1697. if test "${MISSING}" = "" ; then
  1698.     echo You have unpacked all 14 archives.
  1699.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1700. else
  1701.     echo You still need to unpack the following archives:
  1702.     echo "        " ${MISSING}
  1703. fi
  1704. ##  End of shell archive.
  1705. exit 0
  1706.